/*
 *  Copyright (c) 2009, Hugo Augusto Alves
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *      * Redistributions of source code must retain the above copyright
 *        notice, this list of conditions and the following disclaimer.
 *      * Redistributions in binary form must reproduce the above copyright
 *        notice, this list of conditions and the following disclaimer in the
 *        documentation and/or other materials provided with the distribution.
 *      * Neither the appName of the Hugo Augusto Alves nor the
 *        names of its contributors may be used to endorse or promote products
 *        derived from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
 *  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *  DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
 *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package org.wiscriptor.utils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.nio.charset.Charset;
import java.util.ArrayList;
import org.wiscriptor.core.WisProperties;
import org.wiscriptor.internalization.Language;

/**
 *
 * @author Hugo
 */
public class Utils {

    public final static int LOREM_MODE_GENERAL = 1;
    public final static int LOREM_MODE_POETRY = 2;
    public final static String TEXT_HTML = "text/html";
    public final static String TEXT_PLAIN = "text/plain";

    public static enum Status {
        ERROR, SUCCESS, NOT_NEEDED, NOT_WIKI, NOT_PAGE
    }

    /**
     * Erase all StringBuffer
     * @param buffer
     */
    public static void erase(StringBuffer buffer) {
        buffer.delete(0, buffer.length());
    }

    /**
     * Returns the BufferedReader of a file
     * @param filename the string representing the file
     * @return file BufferedReader or null if file does not exist
     */
    public static BufferedReader getFileBuffer(String filename) {
        return getFileBuffer(new File(filename));
    }

    /**
     * Returns the BufferedReader of a file
     * @param file the file to be read
     * @return file BufferedReader or null if file does not exist
     */
    public static BufferedReader getFileBuffer(File file) {
        if (!file.exists()) {
            return null;
        }
        try {
            FileReader reader = new FileReader(file);
            return new BufferedReader(reader);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

    /**
     * Returns the string in UTF-8
     * @param str - the string
     * @return the string in UTF-8
     */
    public static String getStringUTF8(String str) {
        return new String(str.getBytes(), Charset.forName("UTF-8"));
    }

    /**
     * Get the index of the given locale. The return is index of the locale OR index of a locale with same language OR 0
     * @param lang
     * @param country
     * @param langs
     * @return index of the locale OR index of a locale with same language OR 0
     */
    public static int indexOfLanguages(String lang, String country, ArrayList<Language> langs) {
        int aux = -1;
        int defaultIndex = -1;
        for(int i = 0; i < langs.size(); i++) {
            Language l = langs.get(i);
            // exactly match
            if(l.getLang().equals(lang) && l.getCountry().equals(country)) return i;
            // languages match
            if(l.getLang().equals(lang)) aux = i;
            // default match
            if(l.getLang().equals(Language.DEFAULT_LANGUAGE) && l.getCountry().equals(Language.DEFAULT_COUNTRY)) defaultIndex = i;
        }
        if(aux != -1) return aux;
        else if(defaultIndex != -1) return defaultIndex;
        else return 0;
    }

    /**
     * Returns the <code>Lorem Ipsum</code> text
     * @param pCount paragraph / stanza count
     * @param wCount words / verse count
     * @param mode General Text / Poetry Text
     * @return the <code>lorem ipsum</code> text
     */
    public static String getLorem(int pCount, int wCount, int mode) {

        String res = "";
        String aux;

        if (mode == LOREM_MODE_GENERAL) {
            if (pCount < 1) {
                return "";
            }
            if (pCount == 1) {
                return getFirstParagraph(wCount);
            }
            res = getFirstParagraph(wCount);
            for (int i = 0; i < pCount; i++) {
                int k = (int) Math.floor(wCount * (1.05 * Math.random()));
                for (int j = 0; j < k; j++) {
                    if (j == 0) {
                        aux = getRandomString(WisProperties.loremUpperCaseWords);
                    } else {
                        aux = " " + getRandomString(WisProperties.loremLowerCaseWords);
                    }
                    if (Math.random() < 0.1) {
                        aux += (". " + getRandomString(WisProperties.loremUpperCaseWords));
                    } else if (Math.random() < 0.05) {
                        aux += (", " + getRandomString(WisProperties.loremLowerCaseWords));
                    }
                    res += aux;
                }
                res += ".\n";
            }
        } else if (mode == LOREM_MODE_POETRY) {
            for (int i = 0; i < pCount; i++) {
                for (int j = 0; j < wCount; j++) {
                    int kk = (int) (6 + Math.floor(3 * Math.random()));
                    for (int k = 0; k < kk; k++) {
                        if (k == 0) {
                            aux = getRandomString(WisProperties.loremUpperCaseWords);
                        } else {
                            aux = " " + getRandomString(WisProperties.loremLowerCaseWords);
                        }
                        res += aux;
                    }
                    if (Math.random() < 0.13) {
                        res += ".";
                    } else if (Math.random() < 0.13) {
                        res += ",";
                    }
                    res += "\n";
                }
                res += "\n";
            }
        }

        return res;

    }

    /**
     * Returns a random string of a array
     * @param strings the array of strings
     * @return a random string of a array
     */
    public static String getRandomString(String[] strings) {
        return strings[(int) Math.floor(Math.random() * strings.length)];
    }

    /**
     * Returns the first paragraph of the <code>lorem ipsum</code> text
     * @param wCount
     * @return
     */
    public static String getFirstParagraph(int wCount) {
        if (wCount < 20) {
            return WisProperties.getLoremText(1).toString();
        }
        if (wCount < 40) {
            return WisProperties.getLoremText(2).toString();
        }
        if (wCount < 60) {
            return WisProperties.getLoremText(3).toString();
        }
        return WisProperties.getLoremText(4).toString();
    }

    public static int getWordAmount(String str) {
        int count = 0;
        int j;
        for (int i = 0; i < str.length(); i++) {
            // check if is a separator
            if (Character.isWhitespace(str.charAt(i))) {
                count++;
                // go to next word
                do {
                    j = i + 1;
                } while (Character.isWhitespace(str.charAt(j)));
                // if is a single space char do not modify i
                if (j != i + 1) {
                    i = j - 1;
                }
            }
        }
        return count;
    }

    /**
     * Returns the correspondent roman numeral<br />
     * the parameter uppercase means the output format<br />
     * if it is true the output is like IV, VIII, XV, XVI, XXIII, XLII<br />
     * otherwise the output is like iv, viii, xv, xvi, xxiii, xlii
     * @param number the integer that is going to be converted
     * @param uppercase boolean indicating the output format
     * @return
     */
    public static StringBuffer getRomanNumeral(int number, boolean uppercase) {

        char decimal[] = Integer.toString(number).toCharArray();
        char numerals[];
        if (uppercase) {
            numerals = new char[]{'I', 'V', 'X', 'L', 'C', 'D', 'M'};
        } else {
            numerals = new char[]{'i', 'v', 'x', 'l', 'c', 'd', 'm'};
        }
        StringBuffer s = new StringBuffer();
        char c1, c2, c3;
        int j;
        for (int i = 0; i < decimal.length; i++) {
            j = (decimal.length - i - 1) * 2;
            c1 = numerals[j];
            c2 = j + 1 < numerals.length ? numerals[j + 1] : ' ';
            c3 = j + 2 < numerals.length ? numerals[j + 2] : ' ';
            switch (decimal[i]) {
                case '1':
                    s = s.append(c1);
                    break;
                case '2':
                    s = s.append(c1).append(c1);
                    break;
                case '3':
                    s = s.append(c1).append(c1).append(c1);
                    break;
                case '4':
                    s = s.append(c1).append(c2);
                    break;
                case '5':
                    s = s.append(c2);
                    break;
                case '6':
                    s = s.append(c2).append(c1);
                    break;
                case '7':
                    s = s.append(c2).append(c1).append(c1);
                    break;
                case '8':
                    s = s.append(c2).append(c1).append(c1).append(c1);
                    break;
                case '9':
                    s = s.append(c1).append(c3);
            }
        }
        return s;
    }

    public static void trace(String s) {
        System.err.println(s);
    }


}
